template <class R>
class gdiplus_encoder {
public: //some troubles with friend << to the template!?
	const R & img;
	const format fmt;
	const bool alpha;
public:
	gdiplus_encoder(const R & b, format f, bool a) : img(b), fmt(f), alpha(a) {}
};

template <class R>
std::ostream & operator << (std::ostream & s, gdiplus_encoder<R> & c);

template <class R>
inline gdiplus_encoder<R> gdiplus(const R & b, format f, bool a)
	{ return gdiplus_encoder<R>(b, f, a); }

//

template <class R>
class gdiplus_coder {
public:
	R & img;
	const format fmt;
	const bool alpha;
	bool * read_alpha;
public:
	gdiplus_coder(R & b, format f, bool a, bool * ra) : 
		img(b), fmt(f), alpha(a), read_alpha(ra) {}
};

template <class R>
inline std::ostream & operator << (std::ostream & s, gdiplus_coder<R> & c)
	{ return s << gdiplus(const_cast<const R &>(c.img), c.fmt, c.alpha); }

template <class R>
std::istream & operator >> (std::istream & s, gdiplus_coder<R> & c);

template <class R>
inline gdiplus_coder<R> gdiplus(R & b, format f, bool a)
	{ return gdiplus_coder<R>(b, f, a, 0); }

//for reading with alpha channel checking
template <class R>
inline gdiplus_coder<R> gdiplus(R & b, bool * read_alpha, format f, bool a)
	{ return gdiplus_coder<R>(b, f, a, read_alpha); }
